package historymanager.tools;

import java.security.CodeSource;
import java.util.Date;

import org.apache.log4j.Logger;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import java.io.File;

/**
 * Configuration-Class. Helps to get unified access to configuration entries.
 * Configuration-object is singleton. <br/>
 * Changed by Thomas Aulich 25.03.2015:<br/>
 * Configuration Objects: int maxMeasurePointsPerSeries, int
 * maxMeasureValuesPerResultSet<br/>
 * 
 * @author Marcel Bardehle
 * @version 1.0 letze Anderung: log.error + XML-File auf ProgrammPfad geändert
 */
public class Configuration {

	static Logger log = Logger.getLogger(Configuration.class);
	private static Configuration instance;
	private Date myBirthDate;
	private String myDataSourceContext = "java:/comp/env/jdbc/historymanagerDB";
	private long measureRequestInterval; // Daten kommen aus XML
	private String ServerConfigPath;
	private String MeasurepointConfigPath;
	private int urlTimeOut;
	private String logfilePath;
	private int sqlQueryTimeout;
	private double databaseMinFreeSpace;
	private int maxMeasurePointsPerSeries=300;
	private int maxMeasureValuesPerResultSet=1000;

	private Configuration() {
		// Remember the time, when instance was created
		myBirthDate = new Date();
		ReadXMLFile();
	}

	public int getMaxMeasurePointsPerSeries() {
		return maxMeasurePointsPerSeries;
	}

	public void setMaxMeasurePointsPerSeries(int maxMeasurePointsPerSeries) {
		this.maxMeasurePointsPerSeries = maxMeasurePointsPerSeries;
	}

	public int getMaxMeasureValuesPerResultSet() {
		return maxMeasureValuesPerResultSet;
	}

	public void setMaxMeasureValuesPerResultSet(int maxMeasureValuesPerResultSet) {
		this.maxMeasureValuesPerResultSet = maxMeasureValuesPerResultSet;
	}

	public static Configuration getInstance() {
		if (instance == null) {
			// Singleton with double-checked locking
			synchronized (Configuration.class) {
				if (instance == null) {
					instance = new Configuration();
				}
			}
		}
		return instance;
	}

	public Date getBirthDate() {
		return myBirthDate;
	}

	public String getDataSourceContext() {
		return myDataSourceContext;
	}

	public long getMeasureRequestInterval() {
		return measureRequestInterval;
	}

	public String getServerConfigPath() {
		return ServerConfigPath;
	}

	public String getMesurepointConfigPath() {
		return MeasurepointConfigPath;
	}

	public int getUrlTimeOutn() {
		return urlTimeOut;
	}

	public String getLogfilePath() {
		return logfilePath;
	}

	public int getJDBCQueryTimeout() {
		return sqlQueryTimeout;
	}

	public double getDatabaseMinFreeSpace() {
		return databaseMinFreeSpace;
	}

	private void ReadXMLFile() {
		try {

			String propertiesFilePath = "Configuration.xml";
			File fXmlFile = new File(propertiesFilePath);

			// XML-Pfad ermitteln
			if (!fXmlFile.exists()) {
				try {
					CodeSource codeSource = Configuration.class
							.getProtectionDomain().getCodeSource();
					File jarFile = new File(codeSource.getLocation().toURI()
							.getPath());
					String jarDir = jarFile.getParentFile().getPath();
					fXmlFile = new File(jarDir
							+ System.getProperty("file.separator")
							+ propertiesFilePath);
				} catch (Exception ex) {
					log.error("Error while creating XML-path");
				}
			}
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);
			NodeList nList = doc.getElementsByTagName("serverconfigpath");
			ServerConfigPath = nList.item(0).getTextContent().trim()
					+ "/ServerConfig.csv";
			nList = doc.getElementsByTagName("measurepointconfigpath");
			MeasurepointConfigPath = nList.item(0).getTextContent().trim()
					+ "/MeasurePointConfig.csv";
			nList = doc.getElementsByTagName("measureRequestInterval");
			measureRequestInterval = Long.parseLong(nList.item(0)
					.getTextContent().trim()) * 1000 * 60; // Umrechnung in
															// millisekunden
			nList = doc.getElementsByTagName("urlTimeOut");
			urlTimeOut = Integer
					.parseInt(nList.item(0).getTextContent().trim());

			nList = doc.getElementsByTagName("logfilePath");
			logfilePath = nList.item(0).getTextContent().trim();

			nList = doc.getElementsByTagName("SQLQueryTimeout");
			sqlQueryTimeout = Integer.parseInt(nList.item(0).getTextContent()
					.trim()) * 1000; // Eingabe erfolgt in Sekunden. Umrechnung
										// dann in millisekunden
			nList = doc.getElementsByTagName("DatabaseMinimumFreeSpace");
			databaseMinFreeSpace = Double.parseDouble(nList.item(0)
					.getTextContent().trim());
			maxMeasurePointsPerSeries = Integer.parseInt(doc
					.getElementsByTagName("maxMeasurePointsPerSeries").item(0)
					.getTextContent().trim());
			maxMeasureValuesPerResultSet = Integer.parseInt(doc
					.getElementsByTagName("maxMeasureValuesPerResultSet").item(0)
					.getTextContent().trim());

		} catch (Exception e) {
			log.error("XML not found or Tags not found. Message is:"
					+ e.getMessage());
		}

	}
}
